import { Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma.service';
import { PerformanceInsertZod } from '../../types/entrity/Performance.dto';
import { z } from 'zod';
import { CodeErrorAddZod } from 'src/types/dtoExt/CodeError.dto';
import { ErrorMessageAddDto, ErrorMessageAddZod } from 'src/types/dtoExt/ErrorMessage.dto';
import { safeParse } from 'src/utils';
import { CodeErrorInsertZod, CodeErrorUniqueZod } from 'src/types/entrity/CodeError.dto';

@Injectable()
export class MonitorService {
  constructor(
    private readonly mysql: PrismaService,
  ) {}

  /**
   * 保存基础数据/性能指标
   */
  async savePerformance(data: z.infer<typeof PerformanceInsertZod>) {
    return await this.mysql.performance.create({
      data,
    })
  }

  /**
   * 保存代码异常信息
   */
  async saveCodeError(data: z.infer<typeof CodeErrorAddZod>) {
    /**
     * 先保存错误信息
     */
    const record_message = await this.saveErrorMessage(safeParse(ErrorMessageAddZod, data));

    /**
     * 再保存错误记录
     * 如果存在一样的，则time + 1
     */
    const insertData = safeParse(CodeErrorInsertZod, {
      ...data,
      messageId: record_message.id,
    })
    const record_log = await this.mysql.codeError.findFirst({
      where: safeParse(CodeErrorUniqueZod, insertData),
    })
    if (record_log) {
      return await this.mysql.codeError.update({
        where: {
          id: record_log.id,
        },
        data: {
          times: {
            increment: 1,
          }
        }
      })
    } else {
      return await this.mysql.codeError.create({
        data: insertData,
      })
    }
  }

  /**
   * 保存错误信息
   * 如果重复则复用
   * 私有方法，供其它方法调用
   */
  private async saveErrorMessage(data: z.infer<typeof ErrorMessageAddZod>) {
    const record = await this.mysql.errorMessage.findFirst({
      where: {
        ...data
      }
    })
    if (record) {
      return await this.mysql.errorMessage.update({
        where: {
          id: record.id,
        },
        data: {
          times: {
            increment: 1,
          }
        }
      })
    } else {
      return await this.mysql.errorMessage.create({
        data
      })
    }
  }
}
